package com.cbs.android.component.storage.qiniu;


import com.cbs.android.component.log.L;
import com.cbs.android.component.storage.qiniu.entity.QiniuResult;
import com.cbs.component.android.storage.storageinterface.StorageHandler;
import com.cbs.component.android.storage.storageinterface.StorageInterface;
import com.google.gson.Gson;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Hashtable;
import java.util.UUID;

/**
 * Created by broche on 11/12/15.
 */
public class Qiniu implements StorageInterface {
    private static final String TAG = Qiniu.class.getName();
    private boolean debug = false;
    public Hashtable<String, Uploader> uploaders = new Hashtable<>();
    private final Object lock = new Object();

    @Override
    public String upload(String key, String module, String operation, Hashtable<String, String> params, File file, StorageHandler handler) {
        byte[] bytes = file2byte(file);
        return upload(key, module, operation, params, bytes, handler);
    }

    @Override
    public String upload(String module, String operation, Hashtable<String, String> params, byte[] data, StorageHandler handler) {
        return upload(null, module, operation, params, data, handler);
    }

    @Override
    public String upload(String module, String operation, Hashtable<String, String> params, File data, StorageHandler handler) {
        return upload(null, module, operation, params, data, handler);
    }

    @Override
    public String upload(String key, String module, String operation, Hashtable<String, String> params, byte[] data, StorageHandler handler) {
        String id = UUID.randomUUID().toString();
        if (data == null || data.length == 0) {
            handler.onException(id, key, new Exception("file is null"));
            return id;
        }
        Uploader uploader = new Uploader();
        uploader.setDebug(debug);
        addUploader(id, uploader);
        uploader.upload(id, key, module, operation, params, data, new UploaderHandler(this, handler));
        return id;
    }


    @Override
    public void cancel(String id) {
        if (uploaders.containsKey(id)) {
            Uploader uploader = uploaders.get(id);
            if (uploader != null) {
                uploader.cancel();
            }
            removeUploader(id);
        }
    }

    private void addUploader(String id, Uploader uploader) {
        synchronized (lock) {
            uploaders.put(id, uploader);
        }
    }

    private void removeUploader(String id) {
        synchronized (lock) {
            if (uploaders.containsKey(id)) {
                uploaders.remove(id);
            }
        }
    }

    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    private byte[] file2byte(File file) {
        byte[] buffer = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (Exception e) {
            L.e(TAG, "", e);
        }
        return buffer;
    }

    public static class UploaderHandler implements StorageHandler {
        private StorageHandler handler;
        private Qiniu service;

        public UploaderHandler(Qiniu service, StorageHandler handler) {
            this.service = service;
            this.handler = handler;
        }

        @Override
        public void onSuccess(String id, String key, String result) {
            service.removeUploader(id);
            Gson gson = new Gson();
            QiniuResult qiniuResult = gson.fromJson(result, QiniuResult.class);
            handler.onSuccess(id, qiniuResult.getName(), result);
        }

        @Override
        public void onException(String id, String key, Exception e) {
            service.removeUploader(id);
            handler.onException(id, key, e);
        }

        @Override
        public void onProgress(String id, String key, double percent) {
            handler.onProgress(id, key, percent);
        }
    }
}
